fix: prevent silent errors during SSO (account settings) - #38673
Conversation
|
Thanks for the pull request, @Gi-ron! This repository is currently maintained by Once you've gone through the following steps feel free to tag them in a comment and let them know that your changes are ready for engineering review. 🔘 Get product approvalIf you haven't already, check this list to see if your contribution needs to go through the product review process.
🔘 Provide contextTo help your reviewers and other members of the community understand the purpose and larger context of your changes, feel free to add as much of the following information to the PR description as you can:
🔘 Get a green buildIf one or more checks are failing, continue working on your changes until this is no longer the case and your build turns green. DetailsWhere can I find more information?If you'd like to get more details on all aspects of the review process for open source pull requests (OSPRs), check out the following resources: When can I expect my changes to be merged?Our goal is to get community contributions seen and reviewed as efficiently as possible. However, the amount of time that it takes to review and merge a PR can vary significantly based on factors such as:
💡 As a result it may take up to several weeks or months to complete a review and merge your PR. |
|
Hi @Gi-ron! It looks like you're contributing on behalf of eduNEXT. In order to have your CLA check turn green, please have your manager reach out to oscm@axim.org to have you added to our existing entity agreement. |
Thank you! I appreciate it. I've already been enrolled in the CLA, so I'll keep an eye on the PR and wait for the status to update. Thanks again for your comments! |
jignaciopm
left a comment
There was a problem hiding this comment.
Could you check why there're some issues with CI/CD?
felipemontoya
left a comment
There was a problem hiding this comment.
I think the underlying error is clear and needs to be fixed, but the current approach requires some refactor.
|
@Gi-ron also, this PR needs at least one test |
20c06b5 to
a1a4b00
Compare
I added two tests: one for the cases where exceptions are processed in the middleware, and another for the cases where legacy_urls constructs the redirect URL. |
|
Hi @igobranco, @felipemontoya @bra-i-am, @jignaciopm I’ve added some changes to enable rendering error messages in the Account MFE, along with additional tests. The main idea is to capture as many python-social-auth exceptions as possible. Unfortunately, at the moment the Account MFE only renders a user-facing message for duplicate_provider. Could you please take a look at the changes and give me your feedback? It would be really helpful. Thanks in advance! |
07afc3b to
252f946
Compare
|
Hi @Gi-ron, thanks for the PR — the problem statement is correct. A couple of suggestions before this moves forward upstream. The exception mapping may be unnecessary
There is an accepted ADR for this ADR-0029 (Standardize Error Responses, accepted 2026-03-31) defines exactly how errors should reach MFEs. The relevant field is
The TPA case is precisely this — the provider name is context that {
"type": "https://docs.openedx.org/errors/tpa/already-associated",
"title": "Third-Party Account Already Linked",
"status": 409,
"detail": "AuthAlreadyAssociated: tpa-saml",
"user_message": "The Cartão de Cidadão account you selected is already linked to another account.",
"instance": "/auth/login/tpa-saml/"
}Suggested alternative Rather than URL query params, a small endpoint exposing the existing Django message as JSON (consumed on read — flash semantics built in) would let the Account MFE call it once on mount and render a generic This would also align the fix with ADR-0029 rather than establishing a parallel convention that diverges from the platform standard. |
Reading django.contrib.messages marks the whole session storage as consumed, not just the message we want. Without re-queuing the rest, any unrelated message queued in the same session (from some other, unrelated flow) was being silently dropped instead of shown wherever it was actually meant to appear. Now only the first social-auth message is consumed; everything else is re-queued. Also add a drf_yasg schema to the endpoint, matching the convention already used elsewhere in this app, and expand test coverage: message preservation, multiple queued social-auth messages, unrecognized exceptions, and the full set of TPA exception types for both the redirect-dispatch and message-queuing paths.
274ee51 to
8cafd3e
Compare
- use-implicit-booleaness-not-comparison: "list(...) == []" -> "not list(...)" - comparison-with-callable: match.func == view_function needs an explicit disable, same pattern already used elsewhere in this codebase (e.g. common/djangoapps/util/date_utils.py).
|
Thanks for pivoting to the endpoint-based approach, @Gi-ron — this looks much cleaner and matches ADR-0029 well. A couple of small things to close out before this is ready to merge:
|
Description
When linking a third-party identity (SAML, OAuth2, LTI) already linked to another Open edX account,
python-social-authraisesAuthAlreadyAssociated. Its middleware already records this as a Django message, but/account/settingswas a plainRedirectViewstraight toACCOUNT_MICROFRONTEND_URL, which drops Django messages. The error was captured server-side but never reached the user.Fix
ExceptionMiddlewaredecides where to redirect (/account/settingsfor the account-linking flow); the parent middleware records the message for anySocialAuthBaseException.account_settings_redirect_viewis a plain, site-aware redirect, no query params.A new endpoint,
GET /api/user/v1/accounts/third_party_auth_error/, exposes the pending message as{"user_message": "..."}, consumed on read, following the platform's standard shape for MFE-facing errors.Frontend follow-up required
frontend-app-accountdoesn't consume this endpoint yet, it still reads the oldduplicate_providerquery param, which this PR no longer sends. Until it's updated to callGET /api/user/v1/accounts/third_party_auth_error/and renderuser_message, users won't see any error message for this flow.Frontend change: openedx/frontend-app-account#1459
Testing
Automated tests cover all 8
python-social-authexception types (redirect dispatch + message queuing), the new endpoint (auth required, message returned and consumed on read, unrelated Django messages preserved), and the redirect view, run against a real Django/DB, not mocked.Manual reproduction
user_a@example.comanduser_b@example.com.user_aand complete the SAML login flow to link the IdP identity touser_a.user_b, go to Account MFE → Linked Accounts, click Sign in with [provider name] for the same IdP, and complete authentication using the same identity used in step 3.GET /api/user/v1/accounts/third_party_auth_error/returns the pendinguser_message(not yet visible in the UI — see follow-up note above).